/**
 * Copyright (c) 2005-20010 springside.org.cn
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * 
 * $Id: PropertyFilter.java 1205 2010-09-09 15:12:17Z calvinxiu $
 */
package com.guinea.core.orm;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.util.Assert;

import com.guinea.core.utils.BeanUtils;
import com.guinea.core.utils.ConvertUtils;
import com.guinea.core.utils.ServletUtils;
import com.guinea.core.utils.StringUtils;

/**
 * 与具体ORM实现无关的属性过滤条件封装类, 主要记录页面中简单的搜索过滤条件.
 * 
 * @author calvin
 */
public class PropertyFilter {


	/** 多个属性间OR关系的分隔符. */
	public static final String OR_SEPARATOR = "_OR_";

	private MatchType matchType = null;
	private Object matchValue = null;

	private Class propertyClass = null;
	private String[] propertyNames = null;

	public PropertyFilter() {
	}

	/**
	 * @param filterName
	 *            比较属性字符串,含待比较的比较类型、属性值类型及属性列表. eg. LIKES_NAME_OR_LOGIN_NAME
	 * @param value
	 *            待比较的值.
	 */
	public PropertyFilter(final String filterName, final String value) {

		String firstPart = StringUtils.substringBefore(filterName, "_");
		String matchTypeCode = StringUtils.substring(firstPart, 0,
				firstPart.length() - 1);
		String propertyTypeCode = StringUtils.substring(firstPart,
				firstPart.length() - 1, firstPart.length());

		try {
			matchType = new MatchType(new MatchType().getValueByName(matchTypeCode));
		} catch (RuntimeException e) {
			throw new IllegalArgumentException("filter名称" + filterName
					+ "没有按规则编写,无法得到属性比较类型.");
		}

		try {
			propertyClass = new PropertyType().getValueByName(propertyTypeCode);
		} catch (RuntimeException e) {
			throw new IllegalArgumentException("filter名称" + filterName
					+ "没有按规则编写,无法得到属性值类型.");
		}

		String propertyNameStr = StringUtils.substringAfter(filterName, "_");
		Assert.isTrue(StringUtils.isNotBlank(propertyNameStr), "filter名称"
				+ filterName + "没有按规则编写,无法得到属性名称.");
		propertyNames = StringUtils.splitByWholeSeparator(propertyNameStr,
				PropertyFilter.OR_SEPARATOR);

		this.matchValue = ConvertUtils.convertStringToObject(value,
				propertyClass);
	}

//	/**
//	 * 从HttpRequest中创建PropertyFilter列表, 默认Filter属性名前缀为filter.
//	 * 
//	 * @see #buildFromHttpRequest(HttpServletRequest, String)
//	 */
//	public static List buildFromHttpRequest(final HttpServletRequest request) {
//		return buildFromHttpRequest(request, "filter");
//	}

//	/**
//	 * 从HttpRequest中创建PropertyFilter列表
//	 * PropertyFilter命名规则为Filter属性前缀_比较类型属性类型_属性名.
//	 * 
//	 * eg. filter_EQS_name filter_LIKES_name_OR_email
//	 */
//	public static List buildFromHttpRequest(final HttpServletRequest request,
//			final String filterPrefix) {
//		List filterList = new ArrayList();
//
//		// 从request中获取含属性前缀名的参数,构造去除前缀名后的参数Map.
//		Map filterParamMap = ServletUtils.getParametersStartingWith(request,
//				filterPrefix + "_");
//		
//		//add by zhx
////		request.setAttribute("filters",filterParamMap);
//		// 分析参数Map,构造PropertyFilter列表
//		for (Iterator iterator = filterParamMap.entrySet().iterator(); iterator
//				.hasNext();) {
//			Map.Entry entry = (Map.Entry) iterator.next();
//			String filterName = (String) entry.getKey();
//			String value = (String) entry.getValue();
//			// 如果value值为空,则忽略此filter.
//			if (StringUtils.isNotBlank(value)) {
//				PropertyFilter filter = new PropertyFilter(filterName, value);
//				filterList.add(filter);
//			}
//		}
//
//		return filterList;
//	}

	/**
	 * 从HttpRequest中创建PropertyFilter列表
	 * PropertyFilter命名规则为Filter属性前缀_比较类型属性类型_属性名.
	 * 
	 * eg. filter_EQS_name filter_LIKES_name_OR_email
	 */
	public static List buildFromParaMap(final Map filterParamMap) {
		List filterList = new ArrayList();
		
		// 分析参数Map,构造PropertyFilter列表
		for (Iterator iterator = filterParamMap.entrySet().iterator(); iterator
				.hasNext();) {
			Map.Entry entry = (Map.Entry) iterator.next();
			String filterName = (String) entry.getKey();
			String value = entry.getValue() + "";
			// 如果value值为空,则忽略此filter.
			if (StringUtils.isNotBlank(value)) {
				PropertyFilter filter = new PropertyFilter(filterName, value);
				filterList.add(filter);
			}
		}

		return filterList;
	}

	/**
	 * 从HttpRequest中创建page
	 * 
	 */
	public static Page buildPageFromHttpRequest(final HttpServletRequest request,
			final String pagePrefix) {
		Page page = new Page(5);

		// 从request中获取含属性前缀名的参数,构造去除前缀名后的参数Map.
		Map pageParamMap = ServletUtils.getParametersStartingWith(request,
				pagePrefix + "_");
		// 分析参数Map,构造PropertyFilter列表
		for (Iterator iterator = pageParamMap.entrySet().iterator(); iterator
				.hasNext();) {
			Map.Entry entry = (Map.Entry) iterator.next();
			String pageParamName = (String) entry.getKey();
			String value = (String) entry.getValue();
			// 如果value值为空,则忽略此filter.
			if (StringUtils.isNotBlank(value)) {
				try {
					BeanUtils.copyProperty(page, pageParamName, value);
				} catch (IllegalAccessException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}

		return page;
	}

	/**
	 * 获取比较值的类型.
	 */
	public Class getPropertyClass() {
		return propertyClass;
	}

	/**
	 * 获取比较方式.
	 */
	public MatchType getMatchType() {
		return matchType;
	}

	/**
	 * 获取比较值.
	 */
	public Object getMatchValue() {
		return matchValue;
	}

	/**
	 * 获取比较属性名称列表.
	 */
	public String[] getPropertyNames() {
		return propertyNames;
	}

	/**
	 * 获取唯一的比较属性名称.
	 */
	public String getPropertyName() {
		Assert.isTrue(propertyNames.length == 1,
				"There are not only one property in this filter.");
		return propertyNames[0];
	}

	/**
	 * 是否比较多个属性.
	 */
	public boolean hasMultiProperties() {
		return (propertyNames.length > 1);
	}
}
